package com.newlink.building.common_base.http.interceptor

import com.newlink.building.common_base.utils.EnhancedLogger
import okhttp3.*
import okio.Buffer
import java.io.IOException
import java.nio.charset.Charset
import java.nio.charset.StandardCharsets

/**
 * 增强版网络请求日志拦截器
 * @Author: Enhanced by Claude
 * @Date: 2025-09-15
 * @Description: 使用美化的日志格式记录网络请求
 */
class Base_LoggingInterceptor : Interceptor {

    companion object {
        private const val TAG = "NetworkRequest"
        private val UTF8: Charset = StandardCharsets.UTF_8
    }

    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {
        val request = chain.request()

        // 记录请求开始时间
        val startTime = System.currentTimeMillis()

        // 构建请求信息
        val requestUrl = request.url.toString()
        val requestMethod = request.method
        val requestHeaders = formatHeaders(request.headers)
        val requestBody = getRequestBodyString(request)

        // 记录请求日志
        logRequest(requestUrl, requestMethod, requestHeaders, requestBody)

        // 执行请求
        val response: Response
        try {
            response = chain.proceed(request)
        } catch (e: Exception) {
            // 记录请求失败
            val duration = System.currentTimeMillis() - startTime
            logRequestError(requestUrl, requestMethod, e, duration)
            throw e
        }

        // 计算请求耗时
        val endTime = System.currentTimeMillis()
        val duration = endTime - startTime

        // 构建响应信息
        val responseCode = response.code
        val responseMessage = response.message
        val responseHeaders = formatHeaders(response.headers)
        val responseBody = getResponseBodyString(response)

        // 记录响应日志
        logResponse(requestUrl, requestMethod, responseCode, responseMessage, responseHeaders, responseBody, duration)

        return response
    }

    private fun logRequest(url: String, method: String, headers: String?, body: String?) {
        val message = buildString {
            appendLine("🌐 HTTP REQUEST")
            appendLine("┌─────────────────────────────────────")
            appendLine("│ METHOD: $method")
            appendLine("│ URL: $url")
            if (!headers.isNullOrEmpty()) {
                appendLine("│ HEADERS:")
                headers.lines().forEach { line ->
                    if (line.isNotEmpty()) {
                        appendLine("│   $line")
                    }
                }
            }
            if (!body.isNullOrEmpty()) {
                appendLine("│ BODY:")
                body.lines().take(10).forEach { line -> // 限制显示前10行
                    appendLine("│   $line")
                }
                if (body.lines().size > 10) {
                    appendLine("│   ... (truncated)")
                }
            }
            append("└─────────────────────────────────────")
        }
        EnhancedLogger.i(TAG, message)
    }

    private fun logResponse(
        url: String,
        method: String,
        code: Int,
        message: String,
        headers: String?,
        body: String?,
        duration: Long
    ) {
        val statusEmoji = when (code) {
            in 200..299 -> "✅"
            in 300..399 -> "🔀"
            in 400..499 -> "❌"
            in 500..599 -> "💥"
            else -> "❓"
        }

        val responseMessage = buildString {
            appendLine("🌐 HTTP RESPONSE $statusEmoji")
            appendLine("┌─────────────────────────────────────")
            appendLine("│ METHOD: $method")
            appendLine("│ URL: $url")
            appendLine("│ STATUS: $code $message")
            appendLine("│ DURATION: ${duration}ms")
            if (!headers.isNullOrEmpty()) {
                appendLine("│ HEADERS:")
                headers.lines().forEach { line ->
                    if (line.isNotEmpty()) {
                        appendLine("│   $line")
                    }
                }
            }
            if (!body.isNullOrEmpty()) {
                appendLine("│ BODY:")
                body.lines().take(20).forEach { line -> // 响应显示更多行
                    appendLine("│   $line")
                }
                if (body.lines().size > 20) {
                    appendLine("│   ... (truncated)")
                }
            }
            append("└─────────────────────────────────────")
        }

        when (code) {
            in 200..299 -> EnhancedLogger.success(TAG, responseMessage)
            in 400..499 -> EnhancedLogger.w(TAG, responseMessage)
            in 500..599 -> EnhancedLogger.e(TAG, responseMessage)
            else -> EnhancedLogger.i(TAG, responseMessage)
        }

        // 记录性能信息
        EnhancedLogger.performance(TAG, "$method $url", duration)
    }

    private fun logRequestError(url: String, method: String, error: Exception, duration: Long) {
        EnhancedLogger.networkError(
            tag = TAG,
            url = "$method $url",
            error = error.message ?: "Unknown error"
        )
        EnhancedLogger.e(TAG, "请求失败，耗时: ${duration}ms", error)
    }

    private fun formatHeaders(headers: Headers): String? {
        if (headers.size == 0) return null

        return buildString {
            for (i in 0 until headers.size) {
                val name = headers.name(i)
                val value = headers.value(i)

                // 隐敏感信息
                val maskedValue = when {
                    name.equals("Authorization", ignoreCase = true) -> "***MASKED***"
                    name.equals("Cookie", ignoreCase = true) -> "***MASKED***"
                    name.equals("Set-Cookie", ignoreCase = true) -> "***MASKED***"
                    else -> value
                }

                appendLine("$name: $maskedValue")
            }
        }.trimEnd()
    }

    private fun getRequestBodyString(request: Request): String? {
        val requestBody = request.body ?: return null

        if (isPlaintext(requestBody.contentType())) {
            val buffer = Buffer()
            requestBody.writeTo(buffer)

            return buffer.readString(
                requestBody.contentType()?.charset(UTF8) ?: UTF8
            )
        }
        return "[Binary content, ${requestBody.contentLength()} bytes]"
    }

    private fun getResponseBodyString(response: Response): String? {
        val responseBody = response.body ?: return null

        if (!isPlaintext(responseBody.contentType())) {
            return "[Binary content, ${responseBody.contentLength()} bytes]"
        }

        val source = responseBody.source()
        source.request(Long.MAX_VALUE)
        val buffer = source.buffer

        val contentLength = responseBody.contentLength()
        if (contentLength != 0L) {
            return buffer.clone().readString(
                responseBody.contentType()?.charset(UTF8) ?: UTF8
            )
        }

        return null
    }

    private fun isPlaintext(mediaType: MediaType?): Boolean {
        if (mediaType == null) return false

        return when {
            mediaType.type == "text" -> true
            mediaType.subtype.contains("json") -> true
            mediaType.subtype.contains("xml") -> true
            mediaType.subtype.contains("html") -> true
            mediaType.subtype.contains("x-www-form-urlencoded") -> true
            else -> false
        }
    }
}